﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;

namespace ColorTools {
    public partial class LumMapControl : UserControl {
        [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
        public event EventHandler<LumChangeEventArgs> LumChange;

        private readonly Image _lumPointerImage;
        private int _lum;
        private int _hue;
        private int _sat;

        public LumMapControl() {
            InitializeComponent();
            _lumPointerImage = new Bitmap(GetType().Assembly.GetManifestResourceStream("ColorTools.LumPointer.bmp"));
            _lumPointerTrack.BorderStyle = BorderStyle.None;
        }

        public int Lum {
            get { return _lum; }
            set { _lum = value; Refresh(); }
        }

        private void _lumMap_Paint(object sender, PaintEventArgs e) {
            using (Bitmap backBuffer = new Bitmap(_lumMap.Width, _lumMap.Height)) {
                for (int y = 0; y < _lumMap.ClientSize.Height; y++) {
                    int lum = GetLumFromLumMapY(y);
                    DevColor clr = DevColor.FromHLS(_hue, _sat, lum);
                    Color winColor = clr.Color;
                    for (int x = 0; x < backBuffer.Width; x++) {
                        backBuffer.SetPixel(x, y, winColor);
                    }
                }
                e.Graphics.DrawImage(backBuffer, 0, 0);
            }
        }

        private void _lumPointerTrack_Paint(object sender, PaintEventArgs e) {
            int y = GetLumMapYFromLum(Lum);
            ImageAttributes imageAttributes = new ImageAttributes();
            imageAttributes.SetColorKey(Color.White, Color.White);
            Rectangle destRect = new Rectangle(3, y, _lumPointerImage.Width, _lumPointerImage.Height);
            e.Graphics.DrawImage(_lumPointerImage, destRect, 0, 0, _lumPointerImage.Width, _lumPointerImage.Height, GraphicsUnit.Pixel, imageAttributes);
        }

        private int GetLumMapYFromLum(int lum) {
            return _lumMap.ClientSize.Height - (lum * _lumMap.ClientSize.Height / DevColor.HLSMAX);
        }

        private int GetLumFromLumMapY(int y) {
            return (_lumMap.ClientSize.Height - y) * DevColor.HLSMAX / _lumMap.ClientSize.Height;
        }

        private void _lumPointerTrack_MouseMove(object sender, MouseEventArgs e) {
            if (e.Button == MouseButtons.Left) {
                ProcessLumMouseMove(e.Y + (_lumPointerImage.Height / 2));
            }
        }

        private void _lumMap_MouseMove(object sender, MouseEventArgs e) {
            if (e.Button == MouseButtons.Left) {
                ProcessLumMouseMove(e.Y);
            }
        }

        private void ProcessLumMouseMove(int y) {
            int lum = GetLumFromLumMapY(y);
            LumChange(this, new LumChangeEventArgs(lum));
        }

        private void _lumMap_MouseDown(object sender, MouseEventArgs e) {
            ProcessLumMouseMove(e.Y);
        }

        private void _lumPointerTrack_MouseDown(object sender, MouseEventArgs e) {
            ProcessLumMouseMove(e.Y + (_lumPointerImage.Height / 2));
        }

        public void SetColor(int hue, int sat, int lum) {
            _hue = hue;
            _sat = sat;
            _lum = lum;
            Refresh();
        }
    }

    public class LumChangeEventArgs : EventArgs {
        private readonly int _lum;

        public LumChangeEventArgs(int lum) {
            _lum = lum;
        }

        public int Lum {
            get { return _lum; }
        }
    }
}